#include <asm-generic/errno-base.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <unistd.h>

struct msgbuf {
  long mtype;
  char mtext[100];
};

key_t key;
int msg_id;

int main(int argc, char *argv[]) {
  key = ftok(".", 1);
  if (key < 0) {
    perror("ftok fail");
    exit(-1);
  }
  msg_id = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
  if (msg_id < 0 && msg_id == errno) {
    if (errno == EEXIST)
      msg_id = msgget(key, 0666);
  }
  pid_t pid[2];
  int i;
  for (i = 0; i < 2; i++) {
    pid[i] = fork();
    if (pid[i] == 0)
      break;
  }

  if (i == 2) {

    struct msgbuf buf;
    int flg1, flg2;
    flg1 = flg2 = 0;
    while (1) {
      if (flg1 == 0) {
        printf("input to process 1:");
        memset(buf.mtext, 0, 100);
        buf.mtype = pid[0];
        scanf("%s", buf.mtext);
        msgsnd(msg_id, &buf, sizeof(buf), 0);
        if (!strcmp("bye", buf.mtext)) {
          flg1 = 1;
        }
      }

      if (flg2 == 0) {

        printf("input to process 2:");
        memset(buf.mtext, 0, 100);
        buf.mtype = pid[1];
        scanf("%s", buf.mtext);
        msgsnd(msg_id, &buf, sizeof(buf), 0);
        if (!strcmp("bye", buf.mtext)) {
          flg2 = 1;
        }
      }

      if (flg1 == 1 && flg2 == 1)
        break;
    }

    wait(NULL);
    wait(NULL);
    msgctl(msg_id, IPC_RMID, NULL);
  } else if (pid[0] == 0) {
    struct msgbuf buf;
    buf.mtype = getpid();
    while (1) {
      memset(buf.mtext, 0, 100);
      msgrcv(msg_id, &buf, sizeof(buf), getpid(), 0);

      printf("process 1 read is %s\n", buf.mtext);
      if (!strcmp("bye", buf.mtext)) {
        break;
      }
    }
  } else if (pid[1] == 0) {
    struct msgbuf buf;
    buf.mtype = getpid();
    while (1) {
      memset(buf.mtext, 0, 100);
      msgrcv(msg_id, &buf, sizeof(buf), getpid(), 0);

      printf("process 2 read is %s\n", buf.mtext);
      if (!strcmp("bye", buf.mtext)) {
        break;
      }
    }
  }
}
